package cn.iocoder.an.module.business.service.equipmentkeepsettingtype;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.an.module.business.controller.admin.equipmentkeepconfig.vo.EquipmentKeepConfigRespVO;
import cn.iocoder.an.module.business.controller.admin.equipmentmanage.vo.ImportRespVO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepconfig.EquipmentKeepConfigDO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepsetting.EquipmentKeepSettingDO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeeptype.EquipmentKeepTypeDO;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeepconfig.EquipmentKeepConfigMapper;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeepsetting.EquipmentKeepSettingMapper;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeeptype.EquipmentKeepTypeMapper;
import cn.iocoder.an.module.business.service.equipmentkeepconfig.EquipmentKeepConfigService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import cn.iocoder.an.module.business.controller.admin.equipmentkeepsettingtype.vo.*;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepsettingtype.EquipmentKeepSettingTypeDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.business.dal.mysql.equipmentkeepsettingtype.EquipmentKeepSettingTypeMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.an.module.business.enums.ErrorCodeConstants.*;

/**
 * 保养类型 Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
public class EquipmentKeepSettingTypeServiceImpl implements EquipmentKeepSettingTypeService {

    @Resource
    private EquipmentKeepSettingTypeMapper equipmentKeepSettingTypeMapper;

    @Autowired
    private EquipmentKeepSettingMapper equipmentKeepSettingMapper;
    @Resource
    private EquipmentKeepConfigMapper equipmentKeepConfigMapper;
    @Autowired
    private EquipmentKeepTypeMapper equipmentKeepTypeMapper;

    @Override
    public Long createEquipmentKeepSettingType(EquipmentKeepSettingTypeSaveReqVO createReqVO) {
        // 插入
        EquipmentKeepSettingTypeDO equipmentKeepSettingType = BeanUtils.toBean(createReqVO, EquipmentKeepSettingTypeDO.class);
        equipmentKeepSettingTypeMapper.insert(equipmentKeepSettingType);

        // 返回
        return equipmentKeepSettingType.getId();
    }

    @Override
    public void updateEquipmentKeepSettingType(EquipmentKeepSettingTypeSaveReqVO updateReqVO) {
        // 校验存在
        validateEquipmentKeepSettingTypeExists(updateReqVO.getId());
        // 更新
        EquipmentKeepSettingTypeDO updateObj = BeanUtils.toBean(updateReqVO, EquipmentKeepSettingTypeDO.class);
        equipmentKeepSettingTypeMapper.updateById(updateObj);
    }

    @Override
    public void deleteEquipmentKeepSettingType(Long id) {
        // 校验存在
        validateEquipmentKeepSettingTypeExists(id);
        // 删除
        equipmentKeepSettingTypeMapper.deleteById(id);
    }

    @Override
    public void deleteEquipmentKeepSettingTypeListByIds(List<Long> ids) {
        // 删除
        equipmentKeepSettingTypeMapper.deleteByIds(ids);
    }


    private void validateEquipmentKeepSettingTypeExists(Long id) {
        if (equipmentKeepSettingTypeMapper.selectById(id) == null) {
            throw exception(EQUIPMENT_KEEP_SETTING_TYPE_NOT_EXISTS);
        }
    }

    @Override
    public EquipmentKeepSettingTypeDO getEquipmentKeepSettingType(Long id) {
        return equipmentKeepSettingTypeMapper.selectById(id);
    }

    @Override
    public PageResult<EquipmentKeepSettingTypeDO> getEquipmentKeepSettingTypePage(EquipmentKeepSettingTypePageReqVO pageReqVO) {
        return equipmentKeepSettingTypeMapper.selectPage(pageReqVO);
    }


    @Override
    public Map<String, List<EquipmentKeepSettingTypeRespVO>> getEquipmentKeepSettingTypeMapList(EquipmentKeepSettingTypePageReqVO reqVO) {
        Map<String, List<EquipmentKeepSettingTypeRespVO>> map = new HashMap<>();
        map.put("bind", new ArrayList<>());
        map.put("unbound", new ArrayList<>());
        //类型ID或者设备ID
        Long targetId = reqVO.getTargetId();
        //按类型(1)还是按设备(2)
        Integer configType = reqVO.getType();

        if (targetId == null || configType == null) {
            throw exception(EQUIPMENT_KEEP_SETTING_TYPE_NOT_EXISTS);
        }

        //1.查询已绑定的
        LambdaQueryWrapperX<EquipmentKeepConfigDO> configWrapper = new LambdaQueryWrapperX<>();
        configWrapper.eq(EquipmentKeepConfigDO::getConfigType, configType);
        configWrapper.eq(EquipmentKeepConfigDO::getTargetId, targetId);
        List<EquipmentKeepConfigDO> equipmentKeepConfigDOS = equipmentKeepConfigMapper.selectList(configWrapper);
        // 子查询：获取符合条件的 item_id
        List<Long> itemIds = equipmentKeepConfigMapper.selectObjs(
                        new LambdaQueryWrapperX<EquipmentKeepConfigDO>()
                                .select(EquipmentKeepConfigDO::getItemId)
                                .eq(EquipmentKeepConfigDO::getConfigType, configType)
                                .eq(EquipmentKeepConfigDO::getTargetId, targetId)
                ).stream()
                .map(obj -> (Long) obj)
                .collect(Collectors.toList());

        if (itemIds.isEmpty()) {
            //查询所有 已经配置过的 并且是存在的未删除的
            LambdaQueryWrapperX<EquipmentKeepSettingTypeDO> settingTypeWrapper = new LambdaQueryWrapperX<>();
            settingTypeWrapper.eq(EquipmentKeepSettingTypeDO::getStatus, 1);
            settingTypeWrapper.isNotNull(EquipmentKeepSettingTypeDO::getKeepSetting);
            List<EquipmentKeepSettingTypeDO> unboundList = equipmentKeepSettingTypeMapper.selectList(settingTypeWrapper);

            List<EquipmentKeepSettingTypeRespVO> unboundBean = BeanUtils.toBean(unboundList, EquipmentKeepSettingTypeRespVO.class);
            map.put("unbound", unboundBean);
            return map; // 避免 in (empty)
        }
        // 主查询 已绑定的
        MPJLambdaWrapperX<EquipmentKeepSettingTypeDO> bindWrapper = new MPJLambdaWrapperX<>();
        bindWrapper.in(EquipmentKeepSettingTypeDO::getId, itemIds);
        bindWrapper.eq(EquipmentKeepSettingTypeDO::getStatus, 1);
        List<EquipmentKeepSettingTypeDO> bindList = equipmentKeepSettingTypeMapper.selectList(bindWrapper);
        List<EquipmentKeepSettingTypeRespVO> bindBean = BeanUtils.toBean(bindList, EquipmentKeepSettingTypeRespVO.class);
        map.put("bind", bindBean);

        //未绑定的
        MPJLambdaWrapperX<EquipmentKeepSettingTypeDO> unboundWrapper = new MPJLambdaWrapperX<>();
        unboundWrapper.notIn(EquipmentKeepSettingTypeDO::getId, itemIds);
        unboundWrapper.isNotNull(EquipmentKeepSettingTypeDO::getKeepSetting);
        unboundWrapper.eq(EquipmentKeepSettingTypeDO::getStatus, 1);
        List<EquipmentKeepSettingTypeDO> unboundList = equipmentKeepSettingTypeMapper.selectList(unboundWrapper);
        List<EquipmentKeepSettingTypeRespVO> unboundBean = BeanUtils.toBean(unboundList, EquipmentKeepSettingTypeRespVO.class);
        map.put("unbound", unboundBean);
        return map;
    }

    @Override
    public ImportRespVO importList(List<EquipmentKeepTypeSettingImportExcelVO> list, boolean isUpdateSupport) {
        // 1.1 参数校验
        if (CollUtil.isEmpty(list)) {
            throw exception(IMPORT_EQUIPMENT_MANAGE_NOT_EXISTS);
        }

        //2.记录成功或失败记录
        ImportRespVO respVO = ImportRespVO.builder().insertNameList(new ArrayList<>())
                .updateNameList(new ArrayList<>()).failureMap(new LinkedHashMap<>()).build();

        AtomicInteger count = new AtomicInteger(1);
        list.forEach(equipment -> {
            count.incrementAndGet();//记录行号

            // 2.1.2 校验名称
            if (StringUtils.isEmpty(equipment.getName())) {
                respVO.getFailureMap().put("第" + count + "行数据", "名称不能为空!");
                return;
            }

            // 2.1.3 校验状态
            if (equipment.getStatus() == null) {
                respVO.getFailureMap().put("第" + count + "行数据", "状态不能为空!");
                return;
            }

            // 2.1.3 校验周期
            if (equipment.getCycle() == null) {
                respVO.getFailureMap().put("第" + count + "行数据", "周期不能为空!");
                return;
            }


            // 2.1.3 校验提醒天数
            if (equipment.getRemind() == null) {
                respVO.getFailureMap().put("第" + count + "行数据", "提前提醒天数不能为空!");
                return;
            }


            equipmentKeepSettingTypeMapper.insert(BeanUtils.toBean(equipment, EquipmentKeepSettingTypeDO.class));
            respVO.getInsertNameList().add(equipment.getName());
        });
        return respVO;
    }



}